from pathlib import Path
from typing import IO

from bson import ObjectId

from config import settings
from ioservice.common.mongo import insert_one_model
from ioservice.const import file_entity_col
from models.fileserver import FileEntity, FileType
from utils.dateutil import date_now


async def save_file(file_body: IO, filename: str, file_type: FileType, mime, creator=None, display_name=None):
    fid = ObjectId()
    sub_path = Path(filename)
    sub_path = f"{file_type}/{sub_path.stem}-{fid}{sub_path.suffix}"
    save_path = Path(settings.basic['static_basic_path']) / sub_path
    # TODO: use file hash to check file exists.
    if not save_path.parent.exists():
        save_path.parent.mkdir(parents=True)
    with save_path.open(mode='ab') as f:
        for chunk in iter(lambda: file_body.read(1024 * 8), b""):
            f.write(chunk)

    entity = FileEntity(
        id=fid,
        name=filename,
        path=f"/{sub_path}",
        type=file_type,
        mime=mime,
        create_time=date_now()
    )
    if creator:
        entity.creator = creator
    if display_name:
        entity.display_name = display_name
    if file_type == FileType.video:
        # TODO save preview image
        pass
    await insert_one_model(file_entity_col, entity)
    return entity
